package cn.zhiquxing.pipeline;

import cn.zhiquxing.domain.BasicResultVO;
import cn.zhiquxing.domain.ProcessContext;
import cn.zhiquxing.enums.RespStatusEnum;
import cn.zhiquxing.exception.ProcessException;
import lombok.Data;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Data
public class ProcessController {

    /**
     * 模板映射
     */
    private Map<String, ProcessTemplate> templateConfig = null;

    /**
     * 执行责任链
     *
     * @param processContext
     * @return 返回责任链上下文
     */
    public ProcessContext process(ProcessContext processContext) {
        try {
            preCheck(processContext);
        } catch (ProcessException e) {
            return e.getProcessContext();
        }
        List<BusinessProcess> processList = templateConfig.get(processContext.getCode()).getProcessList();
        for (BusinessProcess businessProcess : processList) {
            businessProcess.process(processContext);
            if (Boolean.TRUE.equals(processContext.getNeedBreak())) {
                break;
            }
        }
        return processContext;
    }

    /**
     * 前置校验
     * @param context
     */
    private void preCheck(ProcessContext context) {
        if (Objects.isNull(context)) {
            context = new ProcessContext();
            context.setResponse(BasicResultVO.fail(RespStatusEnum.CONTEXT_IS_NULL));
            throw new ProcessException(context);
        }
        // 业务代码
        String businessCode = context.getCode();
        if (Objects.isNull(businessCode)) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.BUSINESS_CODE_IS_NULL));
            throw new ProcessException(context);
        }
        ProcessTemplate processTemplate = templateConfig.get(businessCode);
        if (Objects.isNull(processTemplate)) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_TEMPLATE_IS_NULL));
            throw new ProcessException(context);
        }
        List<BusinessProcess> processList = processTemplate.getProcessList();
        if (Objects.isNull(processList) || processList.isEmpty()) {
            context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_LIST_IS_NULL));
            throw new ProcessException(context);
        }
    }

}
